//
//  UINavigationController+Consistent.m
//  MengLiao
//
//  Created by xiuxin on 2022/7/15.
//  Copyright © 2022 BaseBusiness. All rights reserved.
//

#import "UINavigationController+Consistent.h"
#import <objc/runtime.h>
#import "THBaseViewController.h"

@implementation UINavigationController (Consistent)

+ (void)load {
    //-- Exchange the original implementation with our custom one.
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        method_exchangeImplementations(class_getInstanceMethod(self, @selector(pushViewController:animated:)),
                                          class_getInstanceMethod(self, @selector(safePushViewController:animated:)));
           
           method_exchangeImplementations(class_getInstanceMethod(self, @selector(popViewControllerAnimated:)),
                                          class_getInstanceMethod(self, @selector(safePopViewControllerAnimated:)));
           
           method_exchangeImplementations(class_getInstanceMethod(self, @selector(popToRootViewControllerAnimated:)),
                                          class_getInstanceMethod(self, @selector(safePopToRootViewControllerAnimated:)));
           
           method_exchangeImplementations(class_getInstanceMethod(self, @selector(popToViewController:animated:)),
                                          class_getInstanceMethod(self, @selector(safePopToViewController:animated:)));
        
    });

}

#pragma mark - setter & getter
- (void)setViewTransitionInProgress:(BOOL)property
{
    NSNumber *number = [NSNumber numberWithBool:property];
    objc_setAssociatedObject(self, @selector(viewTransitionInProgress), number, OBJC_ASSOCIATION_RETAIN);
}

- (BOOL)viewTransitionInProgress {
    NSNumber *number = objc_getAssociatedObject(self, @selector(viewTransitionInProgress));
    return [number boolValue];
}


#pragma mark - Intercept Pop, Push, PopToRootVC
- (NSArray *)safePopToRootViewControllerAnimated:(BOOL)animated {
    if (self.viewTransitionInProgress) return nil;
    
    if (animated) {
        self.viewTransitionInProgress = YES;
    }
    
    NSArray *viewControllers = [self safePopToRootViewControllerAnimated:animated];
    if (viewControllers.count == 0) {
        self.viewTransitionInProgress = NO;
    }
    
    return viewControllers;
}

- (NSArray *)safePopToViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (self.viewTransitionInProgress) return nil;
    
    if (animated){
        self.viewTransitionInProgress = YES;
    }
    
    NSArray *viewControllers = [self safePopToViewController:viewController animated:animated];
    if (viewControllers.count == 0) {
        self.viewTransitionInProgress = NO;
    }
    
    return viewControllers;
}

- (UIViewController *)safePopViewControllerAnimated:(BOOL)animated {
    if (self.viewTransitionInProgress) return nil;
    
    if (animated) {
        self.viewTransitionInProgress = YES;
    }
    
    UIViewController *viewController = [self safePopViewControllerAnimated:animated];
    if (viewController == nil) {
        self.viewTransitionInProgress = NO;
    }
    
    return viewController;
}

- (void)safePushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (self.viewTransitionInProgress == NO) {
        [self safePushViewController:viewController animated:animated];
        
        if (animated) {
            self.viewTransitionInProgress = YES;
        }
    }
}
@end


#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIViewController (JLSafeTransitionLock)

@end

NS_ASSUME_NONNULL_END



@implementation UIViewController (JLSafeTransitionLock)
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        Method m1;
        Method m2;
        
        m1 = class_getInstanceMethod(self, @selector(safeViewDidAppear:));
        m2 = class_getInstanceMethod(self, @selector(viewDidAppear:));
        
        method_exchangeImplementations(m1, m2);
        
        method_exchangeImplementations(class_getInstanceMethod(self, @selector(jl_viewDidAppear:)), class_getInstanceMethod(self, @selector(viewDidAppear:)));
        
    });

}

- (void)safeViewDidAppear:(BOOL)animated {
    self.navigationController.viewTransitionInProgress = NO;
    
    [self safeViewDidAppear:animated];
}

- (void)jl_viewDidAppear:(BOOL)animated
{
    if ([self respondsToSelector:@selector(singleFlag)]) {
        NSMutableArray *mNavc = self.navigationController.viewControllers.mutableCopy;
        for (THBaseViewController *subVC in self.navigationController.viewControllers) {
            if ([subVC respondsToSelector:@selector(singleFlag)] && subVC!=self) {
                if ([[self performSelector:@selector(singleFlag)] isEqualToString:[subVC singleFlag]]) {
                    [mNavc removeObject:subVC];
                    break;//因为每次跳转到判断的话，导航盏中最多已经存在一个，查找到就break，减少事件复杂度
                }
            }
        }
        self.navigationController.viewControllers = mNavc.copy;
    }else if(self.navigationController.viewControllers.count > 2){
        NSMutableArray *mNavc = self.navigationController.viewControllers.mutableCopy;
        for (int i = 1; i < self.navigationController.viewControllers.count - 1; i++) {
            THBaseViewController *subVC = self.navigationController.viewControllers[i];
            if(subVC.removeFromStack){
                [mNavc removeObject:subVC];
                break;//因为每次跳转到判断的话，导航盏中最多已经存在一个，查找到就break，减少事件复杂度
            }
        }
        self.navigationController.viewControllers = mNavc.copy;
    }
    [self jl_viewDidAppear:animated];
}


@end
